package com.xxxx.server.utils;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * FastDFSUtils工具类：
 */

public class FastDFSUtils {
    private static Logger logger = LoggerFactory.getLogger(FastDFSUtils.class);
    /**
     * 1. 初始化客户端
     *  ClientGlobal.init 方法会读取配置文件，并初始化对应的属性。
     */
    static {
        try {
            String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
            ClientGlobal.init(filePath);

        } catch (Exception e) {
            logger.error("FastDFS Client Init Fail!", e);
        }
    }

    /**
     * 2.生成Tracker跟踪服务器端
     * @return
     * @tadminows IOException
     */
    private static TrackerServer getTrackerServer() throws IOException {
        //跟踪器 客户
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getTrackerServer();
        return trackerServer;
    }

    /**
     * 3.生成Storage存储客户端
     * @return
     * @tadminows IOException
     */
    private static StorageClient getStorageClient() throws IOException {
        TrackerServer trackerServer = getTrackerServer();
        StorageClient storageClient = new StorageClient(trackerServer, null);
        return storageClient;
    }



    /**
     * 上传 头像文件
     *
     * @param file
     * @return
     */
    public static String[] upload(MultipartFile file) {
        //1.获取头像的信息
        String name = file.getOriginalFilename();
        logger.info("File Name: " + name);
        long startTime = System.currentTimeMillis();
        String[] uploadResults = null;
        StorageClient storageClient = null;
        try {
            //2. 用storage存储客户端
            storageClient = getStorageClient();
            /**
             *
             * file.getBytes():  头像字节码文件
             * name.substring：名字的后缀名。比如说jpg/pog
             *
             *
             */
            // 3. 用 存储服务器 进行文件上传：      upload_file是封装好的函数，将头像上传到服务器
            uploadResults = storageClient.upload_file(file.getBytes(),
                    name.substring(name.lastIndexOf(".") + 1),
                    null);
            // uploadResults返回的是上传结果：其中包括 文件路径名、文件名等信息
        } catch (IOException e) {
            logger.error("文件上传失败" + name, e);
        } catch (Exception e) {
            logger.error("Non IO Exception when uploadind the file:" + name, e);
        }
        logger.info("upload_file time used:" + (System.currentTimeMillis() -
                startTime) + " ms");

        /**
         * 4. 验证上传结果
         * 如何结果是空的，并且存储客户端为空，说明上传失败。打印失败状态码。
         *      例如：500说明服务器的错误
         */
        if (uploadResults == null && storageClient != null) {
            // 如果说上传失败了，那么就会返回空。在前端展示效果是：头像不变
            logger.error("upload file fail, error code:" + storageClient.getErrorCode());
        }
        //上传文件成功会返回：文件路径和文件名称 【uploadResults】
        logger.info("upload file successfully!!!" + "group_name:" + uploadResults[0] + ", remoteFileName:" + " " + uploadResults[1]);
        // 5. 最后 fastDFS把上传结果，返回给controller
        return uploadResults;
    }

    /**
     * 获取文件信息
     *
     * @param groupName 组的名字
     * @param remoteFileName 远程文件名字
     * @return
     */
    public static FileInfo getFile(String groupName, String remoteFileName) {
        try {
            // 1.获取storage存储服务器
            StorageClient storageClient = getStorageClient();
            return storageClient.get_file_info(groupName, remoteFileName);
        } catch (IOException e) {
            logger.error("IO Exception: Get File from Fast DFS failed", e);
        } catch (Exception e) {
            logger.error("Non IO Exception: Get File from Fast DFS failed", e);
        }
        return null;
    }

    /**
     * 下载文件
     *
     * @param groupName
     * @param remoteFileName
     * @return
     * 流上传文件
     */
    public static InputStream downFile(String groupName, String remoteFileName)
    {
        try {
            // 获取storage存储客户端
            StorageClient storageClient = getStorageClient();
            // 进行下载文件
            byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
            //返回的是数组，转换为流形式
            InputStream ins = new ByteArrayInputStream(fileByte);
            return ins;
        } catch (IOException e) {
            logger.error("IO Exception: Get File from Fast DFS failed", e);
        } catch (Exception e) {
            logger.error("Non IO Exception: Get File from Fast DFS failed", e);
        }

        return null;
    }

    /**
     * 删除文件
     *
     * @param groupName
     * @param remoteFileName
     * @tadminows Exception
     */
    public static void deleteFile(String groupName, String remoteFileName)
    throws Exception {
        // 获取storage存储客户端
        StorageClient storageClient = getStorageClient();
        int i = storageClient.delete_file(groupName, remoteFileName);
        logger.info("delete file successfully!!!" + i);
    }

    /**
     *
     * 获取文件路径
     *
     * @return
     */
    public static String getTrackerUrl() {
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = null;
        StorageServer storeStorage = null;
        try {
            // 获取tracker跟踪器服务
            trackerServer = trackerClient.getTrackerServer();
            // 获取storage存储服务
            storeStorage = trackerClient.getStoreStorage(trackerServer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "http://" + storeStorage.getInetSocketAddress().getHostString() + ":8888/";
    }
}

